package edu.nyu.cs.omnidroid.app.model.db;



import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

/**
 * Database helper class for the Rules table. Defines basic CRUD methods. 
 * <p>
 * This table contains all rule records defined by the user. Every rule is a combination of records
 * in these four tables: Rules, RuleActions, RuleActionParameters, RuleFilters. 
 * </p>
 * 
 * RuleName is the user defined name of the rule; 
 * RuleDesc is the user defined description of the rule;
 * Enabled is whether this rule is activated. 
 * Created is the time stamp of when this rule is created
 * Updated is the time stamp of when this rule is last updated
 * 
 */
public class RuleEventAssociationDbAdapter extends DbAdapter {

  /* Column names */
  public static final String KEY_ASSOCID = "AssocID";
  public static final String KEY_RULEID = "FK_RuleID";
  public static final String KEY_EVENTID = "FK_EventID";

  /* An array of all column names */
  public static final String[] KEYS = { KEY_ASSOCID, KEY_RULEID, KEY_EVENTID };

  /* Table name */
  private static final String DATABASE_TABLE = "RuleEventAssociations";

  /* Create and drop statement. */
  protected static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + " ("
      + KEY_ASSOCID + " integer primary key autoincrement, " 
      + KEY_RULEID + " integer not null, "
      + KEY_EVENTID + " integer not null);";
  protected static final String DATABASE_DROP = "DROP TABLE IF EXISTS " + DATABASE_TABLE;
  

  /**
   * Constructor.
   * 
   * @param database
   *          is the database object to work within.
   */
  public RuleEventAssociationDbAdapter(SQLiteDatabase database) {
    super(database);
  }

  /**
   * Insert a new Rule Association record.
   * 
   * @param ruleId
   *          id in Rule table to associate.
   * @param eventId
   *          id in Event table to associate to.
   * @throws IllegalArgumentException
   *           if there is null within parameters
   */
  public long insert(Long ruleId, Long eventId) {
    if (ruleId == null || eventId == null) {
      throw new IllegalArgumentException("insert parameter null.");
    }

    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_RULEID, ruleId);
    initialValues.put(KEY_EVENTID, eventId);
    
    // Set null because don't use 'null column hack'.
    return database.insert(DATABASE_TABLE, null, initialValues);
  }

  /**
   * Delete an Association record.
   * 
   * @param assocID
   *          is the id of the record.
   * @return true if success, or false otherwise.
   * @throws IllegalArgumentException
   *           if assocID is null
   */
  public boolean delete(Long assocID) {
    if (assocID == null) {
      throw new IllegalArgumentException("primary key null.");
    }
    // Set the whereArgs to null here.
    return database.delete(DATABASE_TABLE, KEY_ASSOCID + "=" + assocID, null) > 0;
  }

  /**
   * Delete all Association records.
   * 
   * @return true if success, or false if failed or nothing to be deleted.
   */
  public boolean deleteAll() {
    // Set where and whereArgs to null here.
    return database.delete(DATABASE_TABLE, null, null) > 0;
  }

  /**
   * Return a Cursor pointing to the record matches the ruleID.
   * 
   * @param assocID
   *          is the id of the record to be fetched.
   * @return a Cursor pointing to the found record.
   * @throws IllegalArgumentException
   *           if ruleID is null
   */
  public Cursor fetch(Long assocID) {
    if (assocID == null) {
      throw new IllegalArgumentException("primary key null.");
    }
    // Set selectionArgs, groupBy, having, orderBy and limit to be null.
    Cursor mCursor = database.query(true, DATABASE_TABLE, KEYS, KEY_ASSOCID + "=" + assocID, null,
        null, null, null, null);
    if (mCursor != null) {
      mCursor.moveToFirst();
    }
    return mCursor;
  }

  /**
   * @return a Cursor that contains all Association records.
   */
  public Cursor fetchAll() {
    // Set selections, selectionArgs, groupBy, having, orderBy to null to fetch all rows.
    return database.query(DATABASE_TABLE, KEYS, null, null, null, null, null);
  }

  /**
   * Return a Cursor that contains all Association records which matches the parameters.
   * 
   * @param ruleId
   *          is the event id, or null to fetch any eventID
   * @param eventId
   *          is name of rule, or null to fetch any ruleName
   * @param orderBy
   *          is the ',' delimited order by columns, or null if no specific order
   * @return a Cursor that contains all Rule records which matches the parameters.
   * @throws SQLiteException
   *           if orderBy is not compiled correctly
   */
  public Cursor fetchAll(Long ruleId, Long eventId, String orderBy) {

    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    qb.setTables(DATABASE_TABLE);
    qb.appendWhere("1=1");
    if (ruleId != null) {
      qb.appendWhere(" AND " + KEY_RULEID + " = " + ruleId);
    }
    if (eventId != null) {
        qb.appendWhere(" AND " + KEY_EVENTID + " = " + eventId);
    }

    // Not using additional selections, selectionArgs, groupBy, having, orderBy, set them to null.
    return qb.query(database, KEYS, null, null, null, null, orderBy);
  }

  /**
   * Update a rule record with specific parameters.
   * 
   * @param assocID
   *          is id of the record to be updated
   * @param ruleId
   *          associated from Rule
   * @param eventId
   *          associated to Rule
   * @return true if success, or false otherwise.
   * @throws IllegalArgumentException
   *           if ruleID is null
   */
  public boolean update(Long assocID, Long ruleId, Long eventId) {

    if (assocID == null) {
      throw new IllegalArgumentException("primary key null.");
    }
    ContentValues args = new ContentValues();
    if (ruleId != null) {
      args.put(KEY_RULEID, ruleId);
    }
    if (eventId != null) {
      args.put(KEY_EVENTID, eventId);
    }

    if (args.size() > 0) {

      // Set whereArg to null here
      return database.update(DATABASE_TABLE, args, KEY_ASSOCID + "=" + assocID, null) > 0;
    }
    return false;
  }
 
  
  public static String getSqliteCreateStatement() {
    return DATABASE_CREATE;
  }
}
